#include "record_index_writer.h"
#include <fstream>
#include <sstream>
#include <iomanip>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "utils_log.h"
#include "utils_file_ex.h"
#include "record_search_cache.h"
#include "record_utils.h"
#include "record_utils.h"

namespace El {
namespace Record {

IndexWriter &IndexWriter::GetInstance()
{
    static IndexWriter instance;
    return instance;
}

bool IndexWriter::WriteVideoIndex(const std::string &absolutePath, const nlohmann::json &videoIndex)
{
    // 构建索引文件路径
    std::string indexPath = absolutePath;

    // 确保目录存在
    std::string dirPath = indexPath;
    size_t pos = dirPath.find_last_of('/');
    if (pos != std::string::npos) {
        dirPath = dirPath.substr(0, pos);
        if (!El::Utils::CreateDirectories(dirPath)) {
            EL_ERROR("Failed to create directory: {}", dirPath);
            return false;
        }
    }

    // 获取或创建索引
    auto indexJson = PathUtils::GetInstance().LoadIndex(indexPath);
    if (indexJson.empty()) {
        indexJson = CreateNewIndex();
    }

    // 添加或更新视频条目
    bool found = false;
    // Ensure "videos" key exists and is an array before iterating
    if (indexJson.contains("videos") && indexJson["videos"].is_array()) {
        // Use value() for safe comparison inside the loop
        auto& videos = indexJson["videos"];
        for (auto it = videos.begin(); it != videos.end(); ++it) {
            // Use value() for safe comparison
            if (it->value("filename", "") == videoIndex.value("filename", "")) {
                // 更新现有条目
                *it = videoIndex;
                found = true;
                break; // 找到并更新后直接退出循环
            }
        }
    } else {
         // Initialize "videos" if it doesn't exist or is not an array
        indexJson["videos"] = nlohmann::json::array();
    }

    if (!found) {
        indexJson["videos"].push_back(videoIndex);
    }

    // 写入文件
    bool success = PathUtils::GetInstance().WriteIndex(indexPath, indexJson);

    // 如果写入成功，更新搜索缓存
    if (success) {
        El::Record::RecordSearchCache::GetInstance().AddVideoFile(videoIndex);
    }

    return success;
}

bool IndexWriter::WriteImageIndex(const std::string &absolutePath, const nlohmann::json &imageIndex)
{
    // 构建索引文件路径
    std::string indexPath = absolutePath;

    // 确保目录存在
    std::string dirPath = indexPath;
    size_t pos = dirPath.find_last_of('/');
    if (pos != std::string::npos) {
        dirPath = dirPath.substr(0, pos);
        if (!El::Utils::CreateDirectories(dirPath)) {
            EL_ERROR("Failed to create directory: {}", dirPath);
            return false;
        }
    }

    // 获取或创建索引
    auto indexJson = PathUtils::GetInstance().LoadIndex(indexPath);
    if (indexJson.empty()) {
        indexJson = CreateNewIndex();
    }

    // 将图片条目添加到索引中
    // Ensure "images" key exists and is an array before pushing
    if (!indexJson.contains("images") || !indexJson["images"].is_array()) {
        indexJson["images"] = nlohmann::json::array();
    }
    indexJson["images"].push_back(imageIndex);

    // 写入文件
    bool success = PathUtils::GetInstance().WriteIndex(indexPath, indexJson);

    // 如果写入成功，更新搜索缓存
    if (success) {
        El::Record::RecordSearchCache::GetInstance().AddImageFile(imageIndex);
    }

    return success;
}

nlohmann::json IndexWriter::CreateNewIndex()
{
    nlohmann::json indexJson;

    auto now = std::chrono::system_clock::now();
    time_t timeT = std::chrono::system_clock::to_time_t(now);
    auto tm = std::localtime(&timeT);

    std::ostringstream dateStr;
    dateStr << std::put_time(tm, "%Y%m%d");

    indexJson["date"] = dateStr.str();
    indexJson["videos"] = nlohmann::json::array();
    indexJson["images"] = nlohmann::json::array();
    EL_INFO("Created new index structure");

    return indexJson;
}

} // namespace Record
} // namespace El